package com.lw.client;

import com.lw.common.Message;
import com.lw.common.MessageType;
import lombok.Data;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.HashMap;
import java.util.Map;

@Data
public class ClientConnectServerThread extends Thread{

    /**
     * 大文件写入流
     * key: fileName
     */
    private Map<String,FileOutputStream> fileOutputStreamMap = new HashMap<>();

    private Socket socket;

    public ClientConnectServerThread(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run() {
        while (true){
            System.out.println("客户端线程等待服务端发送的消息");
            try {
                ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
                Object obj = inputStream.readObject();
                if(obj instanceof Message msg){
                    if(msg.getMsgType().equals(MessageType.MESSAGE_RET_ONLINE_FRIEND)){//好友列表
                        String[] onlineUsers = msg.getContent().split(" ");
                        System.out.println("在线用户列表数："+onlineUsers.length);
                        for (int i = 0; i < onlineUsers.length; i++) {
                            System.out.println("在线用户："+onlineUsers[i]);
                        }
                    } else if(msg.getMsgType().equals(MessageType.MESSAGE_COMM_MES)){//聊天消息
                        String senderId = msg.getSender();
                        String receiveId = msg.getReceiver();
                        String content = msg.getContent();
                        String sendTimeStr = msg.getSendTime();
                        System.out.println(senderId+" 对 "+receiveId+" 说 "+content);
                    }else if(msg.getMsgType().equals(MessageType.MESSAGE_FILE_MES)){//文件
                        String senderId = msg.getSender();
                        String receiveId = msg.getReceiver();
                        byte[] data = msg.getFileBytes();
                        System.out.println(senderId+" 给 "+receiveId+" 发送了文件 ");

                        //将文件保存到客户端临时目录
                        String fileName = msg.getFileName();
                        String tempPath = System.getProperty("user.dir")+ File.separator+"temp"+File.separator+fileName;
                        Files.write(Paths.get(tempPath),data, StandardOpenOption.CREATE,StandardOpenOption.WRITE);
                    }else if(msg.getMsgType().equals(MessageType.MESSAGE_BIG_FILE_MES)){//大文件接收
                        String senderId = msg.getSender();
                        String receiveId = msg.getReceiver();
                        byte[] data = msg.getFileBytes();
                        System.out.println(senderId+" 给 "+receiveId+" 发送了大文件 ");

                        //将文件保存到客户端临时目录
                        String fileName = msg.getFileName();
                        String tempPath = System.getProperty("user.dir")+ File.separator+"temp"+File.separator+fileName;

                        File file = new File(tempPath);
                        FileOutputStream fos = null;
                        if(!file.exists()){
                            file.createNewFile();
                            fos = new FileOutputStream(file,true);
                            fileOutputStreamMap.put(fileName,fos);
                        }else{
                            fos = fileOutputStreamMap.get(fileName);
                        }

                        if(msg.isSendFileOver()){
                            System.out.println("大文件传输完毕");
                            fos.close();
                            fileOutputStreamMap.remove(fileName);
                        }else{
                            fos.write(data);
                        }

                        //下面代码等效于上面追加内容代码，只不过会频繁开关IO流，造成性能浪费
//                        Files.write(Paths.get(tempPath),data, StandardOpenOption.CREATE,StandardOpenOption.WRITE,StandardOpenOption.APPEND);
                    }
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
